package com.sooth.micro.app.service;

import cn.hutool.core.collection.CollUtil;
import com.dream.boot.impl.ServiceImpl;
import com.dream.system.config.Page;
import com.sooth.common.core.exception.ServiceException;
import com.sooth.micro.app.view.MicroAppBo;
import com.sooth.micro.app.view.MicroAppVo;
import com.sooth.micro.entity.service.IMicroEntityService;
import com.sooth.micro.entity.view.MicroEntityBo;
import com.sooth.micro.entity.view.MicroEntityVo;
import com.sooth.micro.field.view.MicroFieldBo;
import com.sooth.micro.model.service.IMicroModelService;
import com.sooth.micro.model.view.MicroModelBo;
import com.sooth.system.datasource.service.ISysDatasourceService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@RequiredArgsConstructor
@Service
public class MicroAppServiceImpl extends ServiceImpl<MicroAppVo, MicroAppBo> implements IMicroAppService {
    private final ISysDatasourceService datasourceService;

    private final IMicroEntityService entityService;

    private final IMicroModelService modelService;

    @Override
    public MicroAppBo selectById(Object id) {
        MicroAppBo microApp = super.selectById(id);
        if (microApp != null) {
            microApp.setModelList(modelService.selectByAppId((Long) id));
        }
        return microApp;
    }

    @Override
    public Page<MicroAppVo> selectPage(Object conditionObject, Page page) {
        Page<MicroAppVo> microAppVoPage = super.selectPage(conditionObject, page);
        Collection<MicroAppVo> rows = microAppVoPage.getRows();
//        if (CollUtil.isNotEmpty(rows)) {
//            Map<Long, String> datasourceMap = new HashMap<>();
//            for (MicroAppVo microAppVo : rows) {
//                Long datasourceId = microAppVo.getDatasourceId();
//                String datasourceName = datasourceMap.get(datasourceId);
//                if (datasourceName == null) {
//                    SysDataSourceBo dataSourceBo = datasourceService.selectById(datasourceId);
//                    if (dataSourceBo != null) {
//                        datasourceName = dataSourceBo.getDatasourceName();
//                    } else {
//                        datasourceName = "";
//                    }
//                    datasourceMap.put(datasourceId, datasourceName);
//                }
//                microAppVo.setDatasourceName(datasourceName);
//            }
//        }
        return microAppVoPage;
    }

    @Override
    public List<MicroEntityVo> getEntityVoList(Long id) {
        MicroAppBo microApp = this.selectById(id);
        if (microApp != null) {
            List<Long> entityIdList = new ArrayList<>(1);
            entityIdList.add(microApp.getEntityId());
            List<MicroModelBo> modelList = this.getModelList(id);
            if (CollUtil.isNotEmpty(modelList)) {
                for (MicroModelBo model : modelList) {
                    if (!entityIdList.contains(model.getJoinEntityId())) {
                        entityIdList.add(model.getJoinEntityId());
                    }
                }
            }
            return entityService.selectVoByIds(entityIdList);
        }
        return new ArrayList<>();
    }

    @Override
    public List<MicroEntityBo> getEntityBoList(Long id) {
        List<MicroEntityBo> entityList = new ArrayList<>(1);
        MicroAppBo microApp = this.selectById(id);
        if (microApp != null) {
            List<Long> entityIdList = new ArrayList<>(1);
            entityIdList.add(microApp.getEntityId());
            List<MicroModelBo> modelList = this.getModelList(id);
            if (CollUtil.isNotEmpty(modelList)) {
                for (MicroModelBo model : modelList) {
                    if (!entityIdList.contains(model.getJoinEntityId())) {
                        entityIdList.add(model.getJoinEntityId());
                    }
                }
            }
            for (Long entityId : entityIdList) {
                MicroEntityBo microEntity = entityService.selectById(entityId);
                if (microEntity == null) {
                    throw new ServiceException("业务实体不存在");
                }
                List<MicroFieldBo> fieldList = entityService.listField(entityId);
                if (CollUtil.isNotEmpty(fieldList)) {
                    microEntity.setFieldList(fieldList);
                }
                entityList.add(microEntity);
            }
        }
        return entityList;
    }

    @Override
    public List<MicroModelBo> getModelList(Long id) {
        return modelService.selectByAppId(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(MicroAppBo microAppBo) {
        super.insertFetchKey(microAppBo);
        List<MicroModelBo> modelList = microAppBo.getModelList();
        if (CollUtil.isNotEmpty(modelList)) {
            for (MicroModelBo model : modelList) {
                model.setAppId(microAppBo.getId());
            }
            modelService.batchInsert(modelList);
        }
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(MicroAppBo microAppBo) {
        int count = super.updateById(microAppBo);
        modelService.deleteByAppId(microAppBo.getId());
        List<MicroModelBo> modelList = microAppBo.getModelList();
        if (CollUtil.isNotEmpty(modelList)) {
            for (MicroModelBo model : modelList) {
                model.setAppId(microAppBo.getId());
            }
            modelService.batchInsert(modelList);
        }
        return count;
    }

//    private void wrapPrim(MicroAppBo microAppBo) {
//        List<String> primaryList = datasourceService.listPrimaryKeys(microAppBo.getDatasourceId(), microAppBo.getTableName());
//        if (CollUtil.isEmpty(primaryList) || primaryList.size() > 1) {
//            throw new ServiceException("数据表：" + microAppBo.getTableName() + "必须存在一个主键字段");
//        }
//        String prim = primaryList.get(0);
//        microAppBo.setPrimaryColumn(primaryList.get(0));
//        List<TableColumnVo> fieldList = datasourceService.listField(microAppBo.getDatasourceId(), microAppBo.getTableName());
//        for (TableColumnVo tableColumnVo : fieldList) {
//            if (prim.equals(tableColumnVo.getColumn())) {
//                microAppBo.setPrimaryType(tableColumnVo.getDataType());
//                break;
//            }
//        }
//        if (microAppBo.getPrimaryType() == null) {
//            throw new ServiceException("数据表：" + microAppBo.getAppName() + "未发现主键：" + prim + "数据类型");
//        }
//        String tableModel = microAppBo.getTableModel();
//        if (StrUtil.isNotEmpty(tableModel)) {
//            List<TableModelVo> tableModelVoList = JsonUtils.parseArray(tableModel, TableModelVo.class);
//            for (TableModelVo tableModelVo : tableModelVoList) {
//                primaryList = datasourceService.listPrimaryKeys(microAppBo.getDatasourceId(), tableModelVo.getJoinTable());
//                if (primaryList.size() > 1) {
//                    throw new ServiceException("数据表：" + microAppBo.getTableName() + "存在多个主键字段");
//                } else if (primaryList.size() == 1) {
//                    prim = primaryList.get(0);
//                    tableModelVo.setPrimaryColumn(prim);
//                    fieldList = datasourceService.listField(microAppBo.getDatasourceId(), tableModelVo.getJoinTable());
//                    for (TableColumnVo tableColumnVo : fieldList) {
//                        if (prim.equals(tableColumnVo.getColumn())) {
//                            tableModelVo.setPrimaryType(tableColumnVo.getDataType());
//                            break;
//                        }
//                    }
//                    if (tableModelVo.getPrimaryType() == null) {
//                        throw new ServiceException("数据表：" + microAppBo.getAppName() + "未发现主键：" + prim + "数据类型");
//                    }
//                }
//
//            }
//            microAppBo.setTableModel(JsonUtils.toJsonString(tableModelVoList));
//        }
//    }
}
